Add Franson's GPS Simulator.
authorrobertl <robertl>
Fri, 19 May 2006 23:10:58 +0000 (23:10 +0000)
committerrobertl <robertl>
Fri, 19 May 2006 23:10:58 +0000 (23:10 +0000)
gpssim.c [new file with mode: 0644]

diff --git a/gpssim.c b/gpssim.c
new file mode 100644 (file)
index 0000000..f9c66fa
--- /dev/null
+++ b/gpssim.c
@@ -0,0 +1,207 @@
+/*
+    Write points to Franson Technology GpsGate simulator
+    Copyright (C) 2006  Robert Lipe, robertlipe@usa.net
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+ */
+#include "defs.h"
+
+#define MYNAME "gpssim"
+
+static FILE *fout;
+static char *wayptspd;
+static char *splitfiles_opt;
+static int splitfiles;
+static char *fnamestr;
+static int trk_count;
+static int doing_tracks;
+
+static
+arglist_t gpssim_args[] = {
+       { "wayptspd", &wayptspd, "Default speed for waypoints (knots/hr)", 
+               NULL, ARGTYPE_FLOAT, ARG_NOMINMAX },
+       { "split", &splitfiles_opt, "Split input into separate files", 
+               "0", ARGTYPE_BOOL, ARG_NOMINMAX },
+       ARG_TERMINATOR
+};
+
+/*
+ * The only thing kind of odd about this format is the "split"
+ * option.  There's some trashing about with the 'splitfiles' toggle 
+ * to ensure that waypoints land in one file and each track and each
+ * route land in files of their own.
+ */
+
+static void
+gpssim_wr_init(const char *fname)
+{
+       fnamestr =  xstrdup(fname);
+       trk_count = 0;
+       splitfiles = splitfiles_opt ? atoi(splitfiles_opt) : 0;
+
+       /* If writing to stdout, never split files */
+       if (0 == strcmp("-",splitfiles_opt)) {
+               splitfiles = 0;
+       }
+
+       if (!splitfiles) {
+               fout = xfopen(fname, "wb", MYNAME);
+       }
+}
+
+static void
+gpssim_wr_deinit(void)
+{
+       if (fout) {
+               fclose(fout);
+               fout = NULL;
+       }
+
+       xfree(fnamestr);
+}
+
+
+/*
+ * All these files are written in binary mode, so put CR/NL pairs
+ * in them explictly in case we're writing from a UNIX-like host.
+ */
+
+static void 
+gpssim_write_sentence(const char *const s)
+{
+       int cksum;
+       fprintf(fout, "$%s*%02X\r\n", s, nmea_cksum(s));
+}
+
+static void
+gpssim_write_spd(double knotsperhour)
+{
+       char obuf[1024];
+
+       snprintf(obuf, sizeof(obuf), "FRSPD,%.2f", knotsperhour);
+       gpssim_write_sentence(obuf);
+}
+
+#define mpsec2knots(n) ((n) * 1.9438445 / 0.51444444)
+
+static void
+gpssim_write_pt(const waypoint *wpt)
+{
+       char obuf[1024];
+       double lat, lon;
+
+       if (wpt->speed > 0) {
+               gpssim_write_spd(mpsec2knots(wpt->speed));
+       }
+
+       lat = degrees2ddmm(wpt->latitude);
+       lon = degrees2ddmm(wpt->longitude);
+
+       snprintf(obuf, sizeof(obuf), "FRWPT,%10.5f,%c,%011.5f,%c,%.1f",
+               fabs(lat), lat < 0 ? 'S' : 'N', 
+               fabs(lon), lon < 0 ? 'W' : 'E', 
+               wpt->altitude == unknown_alt ? 0 : wpt->altitude
+       );
+
+        if ( wpt->creation_time ) {
+               char tbuf[20];
+               int hms, ymd;
+               struct tm *tm;  
+
+               tm = gmtime(&wpt->creation_time);
+                hms = tm->tm_hour * 10000 + tm->tm_min * 100 + tm->tm_sec;
+                ymd = tm->tm_mday * 10000 + tm->tm_mon * 100 + tm->tm_year;
+               snprintf(tbuf, sizeof(tbuf), ",%d,%d",ymd, hms);
+               strcat(obuf, tbuf);
+        }
+
+       gpssim_write_sentence(obuf);
+}
+
+static void
+gpssim_trk_hdr(const route_head *rh)
+{
+       if (splitfiles) {
+               char c[1024];
+               char *ofname = xstrdup(fnamestr);
+               
+               if (fout) {
+                       fatal(MYNAME, ": output file already open.\n");
+               }
+
+               snprintf(c, sizeof(c), "%s%04d.gpssim", 
+                       doing_tracks ? "-track" : "-route",
+                       trk_count++);
+               ofname = xstrappend(ofname, c);
+               fout = xfopen(ofname, "wb", MYNAME);
+               xfree(ofname);
+       }
+       track_recompute(rh, NULL);
+}
+
+static void
+gpssim_trk_ftr(const route_head *rh)
+{
+       if (splitfiles) {
+               fclose(fout);
+               fout = NULL;
+       }
+}
+
+static void
+gpssim_write(void)
+{
+       if (waypt_count()) {
+               if (splitfiles) {
+                       char *ofname = xstrdup(fnamestr);
+                       ofname = xstrappend(ofname, "-waypoints.gpssim");
+                       fout = xfopen(ofname, "wb", MYNAME);
+                       xfree(ofname);
+               }
+               if (wayptspd && wayptspd[0]) {
+                       gpssim_write_spd(atof(wayptspd));
+               }
+               waypt_disp_all(gpssim_write_pt);
+               if (splitfiles) {
+                       fclose(fout);
+                       fout = NULL;
+               }
+       }
+
+       doing_tracks = 1;
+       track_disp_all(gpssim_trk_hdr, gpssim_trk_ftr, gpssim_write_pt);
+
+       trk_count = 0;
+       doing_tracks = 0;
+       route_disp_all(gpssim_trk_hdr, gpssim_trk_ftr, gpssim_write_pt);
+}
+
+
+ff_vecs_t gpssim_vecs = {
+       ff_type_file,
+       { ff_cap_write, ff_cap_write, ff_cap_write },
+       NULL,   
+       gpssim_wr_init, 
+       NULL,   
+       gpssim_wr_deinit,       
+       NULL,
+       gpssim_write,
+       NULL,
+       gpssim_args,
+       CET_CHARSET_ASCII, 0
+};